package com.ttbj.product.api.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ttbj.core.util.DtoTransitionUtils;
import com.ttbj.exception.BusinessException;
import com.ttbj.order.component.OrderCacheComponent;
import com.ttbj.product.api.DriverFacade;
import com.ttbj.product.api.FreightFacade;
import com.ttbj.product.api.OrderFacade;
import com.ttbj.product.api.WaybillFacade;
import com.ttbj.product.bean.dto.DriverDto;
import com.ttbj.product.bean.dto.OrderDto;
import com.ttbj.product.bean.dto.WaybillDto;
import com.ttbj.util.Assert;
import com.ttbj.util.ResultUtil;
import com.ttbj.waybill.dao.WaybillMapper;
import com.ttbj.waybill.po.Waybill;
import com.ttbj.waybill.service.DispachWaybillService;

@Service("waybillFacade")
public class WaybillFacadeImpl implements WaybillFacade {
	private Logger logger = LoggerFactory.getLogger(WaybillFacadeImpl.class);
	@Autowired
	private WaybillMapper waybillMapper = null;

	@Autowired
	private DriverFacade driverFacade = null;

	@Autowired
	private FreightFacade freightFacade = null;

	@Autowired
	private OrderFacade orderFacade = null;

	@Autowired
	DispachWaybillService dispachWaybillService = null;

	@Autowired
	OrderCacheComponent orderCacheComponent = null;

	public static final ConcurrentHashMap<Long, Integer> counter = new ConcurrentHashMap<Long, Integer>();

	public static final int COUNT_DISPATCH_MOST = 2;

	@Override
	public List<WaybillDto> allWayBill(Long orderId) {
		if (null == orderId) {
			logger.info("查询货运单的订单号为null");
			return null;
		}
		return waybillMapper.allWaybill(orderId);
	}

	@Override
	public WaybillDto queryWayBill(WaybillDto waybillDto) {
		if (null == waybillDto) {
			return null;
		}
		WaybillDto waybill = waybillMapper.getWayBill(waybillDto);
		if (null != waybill) {
			waybill = (WaybillDto) DtoTransitionUtils.trans(WaybillDto.class, waybill);
		}
		return waybill;
	}

	@Override
	public List<DriverDto> allDriver(Long orderId) {
		List<WaybillDto> waybills = allWayBill(orderId);
		if (null == waybills || waybills.isEmpty()) {
			return null;
		}
		List<DriverDto> list = new ArrayList<DriverDto>();
		waybills.stream().forEach(waybill -> trans(list, waybill));
		return list;
	}

	private List<DriverDto> trans(List<DriverDto> list, WaybillDto waybill) {
		Long driverId = null;
		if (null == waybill || null == (driverId = waybill.getWaybillDriver())) {
			return list;
		}
		DriverDto driver = null;
		try {
			driver = driverFacade.queryDto(driverId);
			if (null != driver) {
				driver.setWaybillId(waybill.getWaybillId());
				list.add(driver);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	@Override
	public Integer refuseNum(Long driverid) {
		Integer stateNumDay = waybillMapper.stateNumDay(driverid, -1);
		if (null == stateNumDay) {
			stateNumDay = 0;
		}
		return stateNumDay;
	}

	@Override
	public Integer updateState(WaybillDto waybill, Integer stateFlag) throws Exception {
		Assert.assertNonNullField(waybill, "修改配送单状态出现问题原因:waybillId不能为空", 912, null, "waybillId");
		Long waybillOrder = waybill.getWaybillOrder();
		int updateByPrimaryKeySelective = waybillMapper.updateByPrimaryKeySelective(
				(Waybill) DtoTransitionUtils.trans(Waybill.class, waybill.state(stateFlag)));
		if (0 == updateByPrimaryKeySelective) {
			ResultUtil.throwExcepion(ResultUtil.createFail("messages", 912), "修改配送单状态时出错");
		}
		if (!stateFlag.equals(-1)) {// 不允许接单后拒单不修改拒单后的订单状态
			/* 修改订单状态 */
			freightFacade.updateOrderStateByCache(waybillOrder, stateFlag);
			boolean matchStateFull = freightFacade.matchStateFull(waybillOrder, stateFlag);
			if (matchStateFull) { // 订单所属司机全部达到此状态后修改订单状态
				switch (stateFlag) {
				case 1:
					stateFlag = 3;
					break;
				case 2:
					stateFlag = 4;
					break;
				case 3:
					stateFlag = 5;
					break;
				default:
					break;
				}
				orderFacade.updateState(waybillOrder, stateFlag);
			}
		}
		return updateByPrimaryKeySelective;
	}

	@Override
	public Integer newWaybill(OrderDto orderDto) throws Exception {
		if (!Assert.assertNonNullField0(orderDto, "orderId", "orderTruckType", "orderDriverRequire",
				"orderDriverAlready", "orderSender")) {
			throw new BusinessException("99999", "订单参数缺失");
		}
		Long orderId = orderDto.getOrderId();
		Integer countDispatch = getCountDispatch(orderId);
		logger.info("orderId:{} 已自动派单:{}次", orderId, countDispatch);
		if (COUNT_DISPATCH_MOST > countDispatch) { // 继续自动配单
			Integer several = dispachWaybillService.init(orderDto);// 派单数量 车辆不够或是无车辆
			if (several == 0) {// 继续派单
				orderCacheComponent.set(orderId);
				setCountDispatch(orderId, ++countDispatch); // 派单次数
			}
		} else {// 到达最多派单数
			logger.info("自动派单结束，转手动处理");
			autoComple(orderDto);// 修改状态
			removeCountDispatch(orderId);// 删除计数器
		}
		return 0;
	}

	private Integer getCountDispatch(Long orderId) {
		if (counter.isEmpty()) {
			return 0;
		}
		if (!counter.containsKey(orderId)) {
			return 0;
		}
		return counter.get(orderId);
	}

	private void setCountDispatch(Long orderId, Integer count) {
		counter.put(orderId, count);
	}

	private void removeCountDispatch(Long orderId) {
		if (counter.isEmpty()) {
			return;
		}
		if (!counter.containsKey(orderId)) {
			return;
		}
		counter.remove(orderId);
	}

	private void autoComple(OrderDto order) throws Exception {
		order.setOrderAutoComple(0);
		orderFacade.updateOrder(order);
	}

}
